/**
 * 导出工具函数
 */

import { 
  Document, 
  Packer, 
  Paragraph, 
  TextRun, 
  AlignmentType, 
  Table,
  TableCell,
  TableRow,
  WidthType
} from 'docx';
import { HeadingLevel } from 'docx';
import { saveAs } from 'file-saver';
import * as XLSX from 'xlsx-js-style';
import type { EvaluationItem } from '@/types/ProofMapper';

type DocumentElement = Paragraph | Table;

/**
 * 导出证明材料收集清单为Word文档
 * @param items 评估项列表
 * @param fileName 导出文件名，默认为'安全评估证明材料收集清单.docx'
 * @param config 导出配置
 */
export function exportProofMapperToWord(
  items: EvaluationItem[], 
  fileName = '安全评估证明材料收集清单',
  config?: {
    includeNotes?: boolean;
    includeSummary?: boolean;
    pageBreakAfterModule?: boolean;
  }
) {
  if (!items || !items.length) {
    console.warn('没有可导出的评估项');
    return;
  }

  // 按模块和分类分组
  const groupedItems = groupItemsByModuleAndCategory(items);
  
  // 创建文档对象
  const doc = new Document({
    styles: {
      default: {
        heading1: {
          run: {
            font: '仿宋',
            size: 44,
            bold: true
          },
          paragraph: {
            spacing: { after: 480 },
            alignment: AlignmentType.CENTER
          }
        },
        heading2: {
          run: {
            font: '仿宋',
            size: 36,
            bold: true
          },
          paragraph: {
            spacing: { before: 480, after: 360 }
          }
        },
        heading3: {
          run: {
            font: '仿宋',
            size: 32,
            bold: true
          },
          paragraph: {
            spacing: { before: 360, after: 240 }
          }
        }
      }
    },
    sections: [{
      properties: {},
      children: [
        // 文档总标题（一级标题）
        new Paragraph({
          heading: HeadingLevel.HEADING_1,       // 设置为Word一级标题
          children: [new TextRun({ 
            text: '安全评估证明材料收集清单'
          })]
        }),
        
        // 生成时间
        new Paragraph({
          alignment: AlignmentType.CENTER,
          spacing: { after: 720 }, // 段后1.5行间距
          children: [new TextRun({ 
            text: `生成时间：${new Date().toLocaleString()}`, 
            font: '仿宋', 
            size: 28 // 四号字体（14pt）
          })]
        }),

        // 汇总信息（可选）
        ...(config?.includeSummary ? createSummarySection(items) : []),

        // 按模块生成内容
        ...createModuleContent(groupedItems, config)
      ]
    }]
  });

  // 生成文档并保存
  Packer.toBlob(doc).then(blob => {
    saveAs(blob, `${fileName}.docx`);
  });
}

/**
 * 按模块和分类分组
 */
function groupItemsByModuleAndCategory(items: EvaluationItem[]): Map<string, Map<string, EvaluationItem[]>> {
  const grouped = new Map<string, Map<string, EvaluationItem[]>>();
  
  items.forEach(item => {
    if (!grouped.has(item.module)) {
      grouped.set(item.module, new Map());
    }
    
    const moduleCategories = grouped.get(item.module)!;
    if (!moduleCategories.has(item.category)) {
      moduleCategories.set(item.category, []);
    }
    
    moduleCategories.get(item.category)!.push(item);
  });
  
  return grouped;
}

/**
 * 创建汇总信息部分
 */
function createSummarySection(items: EvaluationItem[]): DocumentElement[] {
  const modulesCount = new Set(items.map(item => item.module)).size;
  
  return [
    new Paragraph({
      spacing: { before: 480, after: 240 },
      children: [new TextRun({ 
        text: '汇总信息', 
        bold: true, 
        font: '仿宋', 
        size: 32 // 三号字体（16pt）
      })]
    }),
    new Paragraph({
      spacing: { after: 360 },
      children: [new TextRun({ 
        text: `评估项总数：${items.length} 项    涉及模块：${modulesCount} 个`, 
        font: '仿宋', 
        size: 28 // 四号字体（14pt）
      })]
    })
  ];
}

/**
 * 创建模块内容
 */
function createModuleContent(
  groupedItems: Map<string, Map<string, EvaluationItem[]>>, 
  config?: {
    includeNotes?: boolean;
    pageBreakAfterModule?: boolean;
  }
): DocumentElement[] {
  const paragraphs: DocumentElement[] = [];
  
  groupedItems.forEach((categories, moduleName) => {
    // 模块标题（二级标题）
    paragraphs.push(
      new Paragraph({
        heading: HeadingLevel.HEADING_2,       // 设置为Word二级标题
        children: [new TextRun({ 
          text: moduleName
        })]
      })
    );
    
    // 遍历该模块下的所有分类
    categories.forEach((categoryItems, categoryName) => {
      // 分类标题（三级标题）
      paragraphs.push(
        new Paragraph({
          heading: HeadingLevel.HEADING_3,       // 设置为Word三级标题
          children: [new TextRun({ 
            text: categoryName
          })]
        })
      );
      
      // 遍历该分类下的所有评估项
      categoryItems.forEach((item) => {
        // 核查点
        paragraphs.push(
          new Paragraph({
            spacing: { after: 120 },
            children: [new TextRun({ 
              text: `核查点：${item.checkpoint}`, 
              bold: true, 
              font: '仿宋', 
              size: 28 // 四号字体（14pt）
            })]
          })
        );
        
        // 参考材料表格
        if (item.materials && item.materials.length > 0) {
          paragraphs.push(
            new Paragraph({
              spacing: { after: 120 },
              children: [new TextRun({ 
                text: '参考材料：', 
                bold: true, 
                font: '仿宋', 
                size: 28
              })]
            })
          );
          
          // 创建表格
          const tableRows = item.materials.map((material, materialIndex) => 
            new TableRow({
              children: [
                new TableCell({
                  children: [new Paragraph({
                    children: [new TextRun({ 
                      text: `${materialIndex + 1}`, 
                      font: '仿宋', 
                      size: 24 // 小四号字体（12pt）
                    })]
                  })],
                  width: { size: 20, type: WidthType.PERCENTAGE }
                }),
                new TableCell({
                  children: [new Paragraph({
                    children: [new TextRun({ 
                      text: material, 
                      font: '仿宋', 
                      size: 24
                    })]
                  })],
                  width: { size: 80, type: WidthType.PERCENTAGE }
                })
              ]
            })
          );
          
          // 创建表格并添加到文档
          const table = new Table({
            rows: tableRows,
            width: { size: 100, type: WidthType.PERCENTAGE },
            margins: { top: 120, bottom: 120, left: 120, right: 120 }
          });
          
          // 将表格添加到文档中
          paragraphs.push(table);
        }
        
        // 备注（可选）
        if (config?.includeNotes && item.notes && item.notes.trim()) {
          paragraphs.push(
            new Paragraph({
              spacing: { before: 120, after: 240 },
              children: [new TextRun({ 
                text: `备注：${item.notes}`, 
                font: '仿宋', 
                size: 28
              })]
            })
          );
        } else {
          // 添加段后间距
          paragraphs.push(
            new Paragraph({
              spacing: { after: 240 },
              children: [new TextRun({ text: '', size: 28 })]
            })
          );
        }
        
        // 证明材料附加及说明
        paragraphs.push(
          new Paragraph({
            spacing: { before: 120, after: 120 },
            children: [new TextRun({ 
              text: '证明材料附加及说明：', 
              bold: true, 
              font: '仿宋', 
              size: 28,
              shading: {
                type: 'solid',
                color: 'FFFF00'
              }
            })]
          })
        );
        
        // 添加四行空行用于添加材料使用
        for (let i = 0; i < 4; i++) {
          paragraphs.push(
            new Paragraph({
              spacing: { after: 120 },
              children: [new TextRun({ text: '', size: 28 })]
            })
          );
        }
      });
    });
    
    // 模块结束后可选择自动分页
    if (config?.pageBreakAfterModule) {
      paragraphs.push(
        new Paragraph({
          children: [new TextRun({ text: '' })],
          pageBreakBefore: true
        })
      );
    }
  });
  
  return paragraphs;
}

/**
 * 导出Excel格式的证明材料收集清单
 * @param items 评估项列表
 * @param fileName 导出文件名
 * @param config 导出配置
 */
export function exportProofMapperToExcel(
  items: EvaluationItem[],
  fileName = '安全评估证明材料收集清单',
  config?: {
    includeNotes?: boolean;
    includeSummary?: boolean;
  }
) {
  if (!items || !items.length) {
    console.warn('没有可导出的评估项');
    return;
  }

  try {
    // 1. 数据预处理：按模块分组并处理数据格式
    const processedData = processItemsForExcel(items);
    
    // 2. 创建工作簿
    const wb = XLSX.utils.book_new();
    
    // 3. 生成表格数据
    const tableData = generateTableData(processedData, config);
    
    // 4. 创建工作表
    const ws = XLSX.utils.aoa_to_sheet(tableData.data);
    
    // 5. 应用样式和合并单元格
    applyStylesAndMerges(ws, tableData, processedData);
    
    // 6. 设置列宽
    setColumnWidths(ws);
    
    // 7. 添加工作表到工作簿
    XLSX.utils.book_append_sheet(wb, ws, '证明材料收集清单');
    
    // 8. 导出文件
    XLSX.writeFile(wb, `${fileName}.xlsx`);
    
  } catch (error) {
    console.error('Excel导出失败:', error);
    throw new Error('Excel导出失败');
  }
}

/**
 * 数据预处理：按模块分组并格式化数据
 */
function processItemsForExcel(items: EvaluationItem[]) {
  // 按模块分组
  const moduleGroups = new Map<string, EvaluationItem[]>();
  
  items.forEach(item => {
    if (!moduleGroups.has(item.module)) {
      moduleGroups.set(item.module, []);
    }
    moduleGroups.get(item.module)!.push(item);
  });
  
  // 转换为数组并记录每个模块的起始行号
  const processedData: Array<{
    moduleName: string;
    items: EvaluationItem[];
    startRow: number;
    endRow: number;
  }> = [];
  
  let currentRow = 1; // 从第1行开始（第0行是表头）
  
  moduleGroups.forEach((moduleItems, moduleName) => {
    const startRow = currentRow;
    const endRow = currentRow + moduleItems.length - 1;
    
    processedData.push({
      moduleName,
      items: moduleItems,
      startRow,
      endRow
    });
    
    currentRow += moduleItems.length;
  });
  
  return processedData;
}

/**
 * 生成表格数据（包含表头）
 */
function generateTableData(
  processedData: ReturnType<typeof processItemsForExcel>,
  config?: {
    includeNotes?: boolean;
    includeSummary?: boolean;
  }
) {
  // 表头
  const headers = [
    '模块', 
    '分类', 
    '核查点', 
    '参考材料', 
    '备注', 
    '证明材料附加', 
    '证明材料说明'
  ];
  
  // 数据行
  const dataRows: any[][] = [];
  
  processedData.forEach(moduleGroup => {
    moduleGroup.items.forEach(item => {
      // 将参考材料数组添加序号前缀并用换行符连接
      const materialsText = item.materials.map((material, index) => `${index + 1}. ${material}`).join('\n');
      
      const row = [
        moduleGroup.moduleName,           // 模块
        item.category,                    // 分类
        item.checkpoint,                  // 核查点
        materialsText,                    // 参考材料（多条用换行符分隔，带序号）
        config?.includeNotes ? item.notes : '', // 备注
        '',                               // 证明材料附加（留空供用户填写）
        ''                                // 证明材料说明（留空供用户填写）
      ];
      
      dataRows.push(row);
    });
  });
  
  return {
    headers,
    data: [headers, ...dataRows],
    totalRows: dataRows.length + 1 // 包含表头
  };
}

/**
 * 应用样式和合并单元格
 */
function applyStylesAndMerges(
  ws: XLSX.WorkSheet,
  tableData: ReturnType<typeof generateTableData>,
  processedData: ReturnType<typeof processItemsForExcel>
) {
  // 1. 设置表头样式
  const headerStyle = {
    font: {
      name: '仿宋',
      sz: 14, // 小四号字体（14pt，Excel中字号单位不同）
      bold: true
    },
    alignment: {
      horizontal: 'center' as const,
      vertical: 'center' as const,
      wrapText: true
    },
    fill: {
      fgColor: { rgb: 'F2F2F2' } // 浅灰色背景
    }
  };
  
  // 2. 设置内容样式
  const contentStyle = {
    font: {
      name: '仿宋',
      sz: 14, // 小四号字体
      bold: false
    },
    alignment: {
      horizontal: 'left' as const,
      vertical: 'top' as const,
      wrapText: true
    }
  };
  
  // 3. 设置模块列样式（合并单元格后需要特殊处理）
  const moduleColumnStyle = {
    font: {
      name: '仿宋',
      sz: 14, // 小四号字体
      bold: false
    },
    alignment: {
      horizontal: 'center' as const,
      vertical: 'center' as const,
      wrapText: true
    }
  };
  
  // 4. 应用表头样式
  for (let col = 0; col < tableData.headers.length; col++) {
    const cellAddress = XLSX.utils.encode_cell({ r: 0, c: col });
    if (!ws[cellAddress]) ws[cellAddress] = {};
    ws[cellAddress].s = headerStyle;
  }
  
  // 5. 应用内容样式
  for (let row = 1; row < tableData.totalRows; row++) {
    for (let col = 0; col < tableData.headers.length; col++) {
      const cellAddress = XLSX.utils.encode_cell({ r: row, c: col });
      if (!ws[cellAddress]) ws[cellAddress] = {};
      
      // 为不同列设置不同的样式
      if (col === 0) {
        // 模块列：居中对齐
        ws[cellAddress].s = moduleColumnStyle;
      } else {
        // 其他列：左对齐、顶部对齐、自动换行
        ws[cellAddress].s = contentStyle;
      }
    }
  }
  
  // 6. 合并相同模块的单元格
  const merges: XLSX.Range[] = [];
  
  processedData.forEach(moduleGroup => {
    if (moduleGroup.items.length > 1) {
      // 合并模块列（第0列）
      merges.push({
        s: { r: moduleGroup.startRow, c: 0 }, // 起始位置
        e: { r: moduleGroup.endRow, c: 0 }   // 结束位置
      });
    }
  });
  
  if (merges.length > 0) {
    ws['!merges'] = merges;
  }
}

/**
 * 设置列宽
 */
function setColumnWidths(ws: XLSX.WorkSheet) {
  // 列宽设置（单位：字符宽度）
  const colWidths = [
    { wch: 15 }, // 模块
    { wch: 20 }, // 分类
    { wch: 50 }, // 核查点
    { wch: 60 }, // 参考材料
    { wch: 40 }, // 备注
    { wch: 35 }, // 证明材料附加
    { wch: 35 }  // 证明材料说明
  ];
  
  ws['!cols'] = colWidths;
  
  // 设置行高（增加行高以确保多行文本完整显示）
  if (!ws['!rows']) ws['!rows'] = [];
  
  // 为所有行设置较大的行高以适应多行文本
  for (let i = 0; i < 1000; i++) { // 假设最多1000行
    ws['!rows'][i] = { hpt: 120 }; // 设置更大的行高（120磅，约6行文本的高度）
  }
}
